﻿using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;

namespace Notoric.View.Music.CWNotation.Controls
{
    /// <summary>
    /// Visualizes a key signature sign.
    /// </summary>
    public partial class KeySignatureSign : UserControl
    {
        #region Constructors

        /// <summary>
        /// Creates a new <see cref="KeySignatureSign"/> instance.
        /// </summary>
        public KeySignatureSign()
        {
            InitializeComponent();
        }

        #endregion

        #region Event Handlers

        /// <summary>
        /// Occurs when the data context (visualized key signature sign) has changed.
        /// </summary>
        /// <remarks>
        /// <b>Operation:</b><br/>
        /// The handler unbinds from the old sign's <see cref="ViewModel.ViewModelElement.PropertyChanged"/>, 
        /// caches the new visualized sign, binds to its <see cref="ViewModel.ViewModelElement.PropertyChanged"/> event
        /// and calls <see cref="SetVisualization"/>.
        /// </remarks>
        /// <param name="sender">Object where the event handler is attached</param>
        /// <param name="e">Event data</param>
        private void UserControl_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            if (sign != null)
                sign.PropertyChanged -= sign_PropertyChanged;

            sign = (ViewModel.Elements.CWNotation.KeySignatureSign)DataContext;

            if (sign != null)
                sign.PropertyChanged += new PropertyChangedEventHandler(sign_PropertyChanged);

            SetVisualization();
        }

        /// <summary>
        /// Occurs when the value of some of the sign's properties has changed.
        /// </summary>
        /// <remarks>
        /// <b>Operation:</b><br/>
        /// If the modified property is <see cref="Notoric.ViewModel.Elements.CWNotation.KeySignatureSign.AccidentalType"/>,
        /// the handler calls the <see cref="SetVisualization"/> method.
        /// </remarks>
        /// <param name="sender">Object that has sent the event</param>
        /// <param name="e">Event data</param>
        private void sign_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "AccidentalType")
                SetVisualization();
        }

        /// <summary>
        /// Occurs when the contol has been loaded.
        /// </summary>
        /// <remarks>
        /// <b>Operation:</b><br/>
        /// The handler caches the visualized sign, binds to its <see cref="ViewModel.ViewModelElement.PropertyChanged"/> event
        /// and calls <see cref="SetVisualization"/>.
        /// </remarks>
        /// <param name="sender">Object where the event handler is attached</param>
        /// <param name="e">Event data</param>
        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            sign = (ViewModel.Elements.CWNotation.KeySignatureSign)DataContext;

            if (sign != null)
                sign.PropertyChanged += new PropertyChangedEventHandler(sign_PropertyChanged);

            SetVisualization();
        }

        #endregion

        #region Private Methods

        /// <summary>
        /// Selects the symbol and margin for the <see cref="PART_AccidentalSymbol"/> control
        /// to visualize the accidental type.
        /// </summary>
        private void SetVisualization()
        {
            if (sign == null)
            {
                PART_AccidentalSymbol.Text = "";
                return;
            }

            var spaceSize = sign.FindOwner<ViewModel.Elements.CWNotation.Staff>().SpaceSize;

            switch (sign.AccidentalType)
            {
                case ViewModel.Elements.CWNotation.AccidentalType.DoubleFlat:
                    PART_AccidentalSymbol.Text = "º";
                    break;
                case ViewModel.Elements.CWNotation.AccidentalType.DoubleNeutral:
                    PART_AccidentalSymbol.Text = "nn";
                    break;
                case ViewModel.Elements.CWNotation.AccidentalType.DoubleSharp:
                    PART_AccidentalSymbol.Text = "Ü";
                    break;
                case ViewModel.Elements.CWNotation.AccidentalType.Flat:
                    PART_AccidentalSymbol.Text = "b";
                    break;
                case ViewModel.Elements.CWNotation.AccidentalType.Neutral:
                    PART_AccidentalSymbol.Text = "n";
                    break;
                case ViewModel.Elements.CWNotation.AccidentalType.Sharp:
                    PART_AccidentalSymbol.Text = "#";
                    break;
                default:
                    PART_AccidentalSymbol.Text = "";
                    break;
            }

            PART_AccidentalSymbol.Margin = new Thickness(0, -5.5 * spaceSize, 0, 0);
        }

        #endregion

        #region Private Fields

        /// <summary>
        /// Holds the visualized key signature sign.
        /// </summary>
        private ViewModel.Elements.CWNotation.KeySignatureSign sign;

        #endregion
    }
}
